
/***************************************************************************
*
* Title          : Arduino based sACN (E1.31) -> LED Pixel, Digital LED Strip gateway for WS2801
* Version        : v 0.4 beta
* Last updated   : 21.08.2013
* Target         : Arduino Mega 2560
* Author         : David Stone - david <at> uberatomic <dot> com
*
*
***************************************************************************
 This program is free software; you can redistribute it and/or 
 modify it under the terms of the GNU General Public License 
 as published by the Free Software Foundation; either version 2 of 
 the License, or (at your option) any later version. 

 This program is distributed in the hope that it will be useful, 
 but WITHOUT ANY WARRANTY; without even the implied warranty of 
 MERCHANTABILITY or FITNESS FOR A PsacnICULAR PURPOSE. See the GNU 
 General Public License for more details. 

 If you have no copy of the GNU General Public License, write to the 
 Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 

 For other license models, please contact the author.

;***************************************************************************/

#include <Ethernet.h>
#include <SPI.h>
#include <EthernetUdp.h>
#include "sacn_packet.h"
#include "Adafruit_WS2801.h"

uint8_t factory_mac          [6] = {   1,   2,   3,   0,   0,  10}; // the mac address of node
uint8_t factory_localIp      [4] = {   2,   10,   0,  20};           // the IP address of node
//uint8_t factory_broadcastIp  [4] = {   2, 255, 255, 255};           // broadcast IP address
uint8_t factory_gateway      [4] = {   2,   10,   0,   5};           // gateway IP address (use ip address of controller)
uint8_t factory_subnetMask   [4] = { 255,   0,   0,   0};           // network mask (sacn-net use 'A' network type)



uint8_t  factory_longname     [SOURCE_NAME_ADDR];

uint8_t factory_subnet = 0;

sacn_node_s *sacnNode;

int     packet_type;

const int MAX_BUFFER_UDP = 680;
volatile uint8_t packetBuffer[MAX_BUFFER_UDP]; //buffer to store incoming data

EthernetUDP Udp; //Set up UDP Receiving
int dataPin  = 2;   
int clockPin = 3;    
Adafruit_WS2801 strip = Adafruit_WS2801(170,dataPin,clockPin); //declare strip


void setup() 
{
  sprintf((char *)factory_longname, "SACN NODE\0");
  Ethernet.begin(factory_mac, factory_localIp); 
  Udp.begin(STREAM_IP_PORT);
  strip.begin();
}

void loop() 
{

  if( Udp.parsePacket() > 600){ 
   
    handle_packet();
  }
  else{
   
  };
  
}

void handle_packet()
{ 
  Udp.read((uint8_t *)packetBuffer, MAX_BUFFER_UDP);  //Read Packet into buffer
  sacnNode = (sacn_node_s *)packetBuffer;  //Make a structure pointer to buffer
  packet_type = get_packet_type();
  
  if(packet_type == 0)  // bad packet
  {
    return;
  }  
  if(packet_type == 1)
  {
      handle_dmx();
  }   
}

uint8_t get_packet_type() //this gets sacn packet type
{
  if (!memcmp(sacnNode->packetId, ACN_IDENTIFIER, ACN_IDENTIFIER_SIZE)) //Compare Packet to known identifier
  {
    return 1; 
  } 
  return 0;
}

int handle_dmx()
{
  if((uint8_t)( ((sacnNode->universeNo[2] << 8) & 0xff00) | (sacnNode->universeNo[1] & 0x00FF) ) == 1) //Turn 2 bytes into full universe number and check
  {
    memcpy((uint8_t *)strip.pixels, sacnNode->dataValues+1, 512); //Copy DMX Data skipping the first data start byte
  }
  strip.show(); //LX1 - GO!!
}


